package com.application.examples.utils;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author chailonglong
 * @date 2019-10-12 10:41
 */
public final class ImageUtils {
    private static final Logger logger = LoggerFactory.getLogger(ImageUtils.class);
    /**
     * 将图片base64保存为本地图片
     *
     * @param base64 图片base64
     * @param path   图片保存的地址
     * @return 是否成功
     */
    public static boolean saveImageFromBase64(String base64, String path) {
        try {
            if (StringUtils.isEmpty(base64)) {
                logger.error("saveImageFromBase64 base64 is empty");
                return false;
            }
            if (StringUtils.isEmpty(path)) {
                logger.error("saveImageFromBase64 path is empty");
                return false;
            }
            byte[] data = Base64.decodeBase64(base64);
            return saveImageByByte(data, path);
        } catch (Exception e) {
            logger.error("saveImageFromBase64 {} has error", path, e);
        }
        return false;
    }


    /**
     * 获取远程图片base64
     *
     * @param imageUrl 远程图片访问地址
     * @return 图片base64
     */
    public static String getBase64FromImageUrl(String imageUrl) {
        try {
            if (StringUtils.isEmpty(imageUrl)) {
                logger.error("getBase64FromImageUrl imageUrl is empty");
                return null;
            }
            byte[] data = getByteFromImageUrl(imageUrl);
            if (data != null) {
                return Base64.encodeBase64String(data);
            }
        } catch (Exception e) {
            logger.error("getBase64FromImageUrl {} has error", imageUrl, e);
        }
        return null;
    }

    /**
     * 通过本地图片地址获取图片base64
     *
     * @param path 本地图片绝对路径
     * @return 图片base64
     */
    public static String getBase64FromLocalFile(String path) {
        try {
            if (StringUtils.isEmpty(path)) {
                logger.error("getBase64FromLocalFile path is empty");
                return null;
            }
            byte[] data = getByteFromFile(new File(path));
            if (data != null) {
                return Base64.encodeBase64String(data);
            }
        } catch (Exception e) {
            logger.error("getBase64FromLocalFile {} has error", path, e);
        }
        return null;
    }


    /**
     * 获取图片文件byte[]
     *
     * @param file 图片文件
     * @return 文件byte[]
     */
    public static byte[] getByteFromFile(File file) {
        try {
            if (file == null) {
                logger.error("getByteFromLocalImage file is null ");
                return null;
            }
            return FileUtils.readFileToByteArray(file);
        } catch (Exception e) {
            if (file != null) {
                try {
                    logger.error("getByteFromFile {} has error ", file.getPath(), e);
                } catch (Exception e1) {
                    logger.error("getByteFromFile has error ", e);
                }
            }
        }
        return null;
    }

    /**
     * 获取远程图片的byte
     *
     * @param imageUrl 远程图片的url
     * @return 文件byte[]
     */
    public static byte[] getByteFromImageUrl(String imageUrl) {
        HttpURLConnection conn = null;
        InputStream inStream = null;

        try {
            URL url = new URL(imageUrl);
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5 * 1000);
            inStream = conn.getInputStream();
            return readInputStream(inStream);
        } catch (Exception e) {
            logger.error("getByteFromImageUrl error", e);
        } finally {
            try {
                if (inStream != null) {
                    inStream.close();
                }
                if (conn != null) {
                    conn.disconnect();
                }
            } catch (Exception e1) {
                logger.error("getByteFromImageUrl release connection error", e1);
            }
        }
        return null;
    }

    private static byte[] readInputStream(InputStream inStream) throws Exception {
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[10240];
        int len;
        while ((len = inStream.read(buffer)) != -1) {
            outStream.write(buffer, 0, len);
        }
        inStream.close();
        return outStream.toByteArray();
    }

    /**
     * 将图片byte[] 保存为本地图片
     *
     * @param data     图片的byte[]
     * @param savePath 图片保存到本地的绝对路径及文件名
     * @return 是否成功
     */
    public static boolean saveImageByByte(byte[] data, String savePath) {
        try {
            ByteArrayInputStream in = new ByteArrayInputStream(data);
            BufferedImage image = ImageIO.read(in);
            return ImageIO.write(image, "jpg", new File(savePath));
        } catch (Exception e) {
            logger.error("saveImageByByte error", e);
        }
        return false;
    }

}
